import java.io.IOException;
import java.math.BigDecimal;
import java.util.Scanner;

import com.pi4j.component.servo.Servo;
import com.pi4j.component.servo.impl.GenericServo;
import com.pi4j.component.servo.impl.PCA9685GpioServoProvider;
import com.pi4j.gpio.extension.pca.PCA9685GpioProvider;
import com.pi4j.gpio.extension.pca.PCA9685Pin;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;
import com.pi4j.util.CommandArgumentParser;
import com.pi4j.util.Console;
import com.pi4j.wiringpi.SoftPwm;
import com.raspoid.PWMPin;


public class MotorPCA {
	public static void main(String[] args) throws InterruptedException, UnsupportedBusNumberException, IOException   {

		System.out.println("<--Pi4J--> GPIO Control Example ... started.");

        // create gpio controller
//		for (int i = 0; i < 3; i++) {
			 final GpioController gpio = GpioFactory.getInstance();
		        // provision gpio pin #01 as an output pin and turn on
			 	Pin pin8 = CommandArgumentParser.getPin(
		                RaspiPin.class,    // pin provider class to obtain pin instance from
		                RaspiPin.GPIO_24,  // default pin if no pin argument found
		                args);
			 	Pin pin9 = CommandArgumentParser.getPin(
		                RaspiPin.class,    // pin provider class to obtain pin instance from
		                RaspiPin.GPIO_25,  // default pin if no pin argument found
		                args);
		        final GpioPinDigitalOutput out8 = gpio.provisionDigitalOutputPin(pin8, "MyLED", PinState.LOW);
		        final GpioPinDigitalOutput out9 = gpio.provisionDigitalOutputPin(pin9, "MyLED", PinState.LOW);
		        Pin pin = CommandArgumentParser.getPin(
		                RaspiPin.class,    // pin provider class to obtain pin instance from
		                RaspiPin.GPIO_23,  // default pin if no pin argument found
		                args);             // argument array to search in

		        GpioPinPwmOutput pwm = gpio.provisionPwmOutputPin(pin);

		        // you can optionally use these wiringPi methods to further customize the PWM generator
		        // see: http://wiringpi.com/reference/raspberry-pi-specifics/
		        com.pi4j.wiringpi.Gpio.pwmSetMode(com.pi4j.wiringpi.Gpio.PWM_MODE_MS);
		        com.pi4j.wiringpi.Gpio.pwmSetRange(1000);
		        com.pi4j.wiringpi.Gpio.pwmSetClock(500);
		        
		        // set shutdown state for this pin
		        out8.setShutdownOptions(true, PinState.LOW);
		        out9.setShutdownOptions(true, PinState.LOW);
		        Thread.sleep(1000);
		        final Console console = new Console();
		        console.promptForExit();
		        out8.setState(PinState.HIGH);
	        	out9.setState(PinState.LOW);
	        	Thread.sleep(2000);
	        	pwm.setPwmRange(100);
	        	System.out.println("===");
	        	for (int i = 0; i < 100; i+=10) {
	        		pwm.setPwm(i);
	        		System.out.println("i="+i);

	        		Thread.sleep(1000);
				}
	        	 
	        	out8.setState(PinState.HIGH);
	        	out9.setState(PinState.LOW);
	        	Thread.sleep(2000);
	        	pwm.setPwmRange(100);
	        	System.out.println("===");
	        	for (int i = 0; i < 100; i+=10) {
	        		pwm.setPwm(i);
	        		System.out.println("i="+i);
	        		Thread.sleep(1000);
				}
	        	
	        	out8.setState(PinState.HIGH);
	        	out9.setState(PinState.HIGH);
	        	Thread.sleep(2000);
		        gpio.unprovisionPin(out8,out9);
		        pwm.setPwm(0);
		        gpio.shutdown();
//		        System.out.println("--> GPIO shutdown!!");
//		}
       

	
	}
	private static GpioPinPwmOutput[] provisionPwmOutputs(final PCA9685GpioProvider gpioProvider) {
	    GpioController gpio = GpioFactory.getInstance();
	    GpioPinPwmOutput myOutputs[] = {
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_00, "Pulse 00"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_01, "Pulse 01"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_02, "Pulse 02"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_03, "Pulse 03"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_04, "Pulse 04"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_05, "Pulse 05"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_06, "Pulse 06"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_07, "Pulse 07"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_08, "Pulse 08"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_09, "Pulse 09"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_10, "Always ON"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_11, "Always OFF"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_12, "Servo pulse MIN"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_13, "Servo pulse NEUTRAL"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_14, "Servo pulse MAX"),
	            gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_15, "not used")};
	    return myOutputs;
	}
}
